home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Almathera Ten Pack 3: CDPD 3
/
Almathera Ten on Ten - Disc 3: CDPD3.iso
/
scope
/
151-175
/
scopedisk168
/
asmmacros
/
asmmacros_02.doc
< prev
next >
Wrap
Text File
|
1995-03-19
|
87KB
|
2,833 lines
*****************************************************************************
*
* AsmMacros
*
* Rev. 01 14 Mar 88 - Initial release.
* Rev. 02 9 Feb 89 - Added support for CAPE-68K assembler and
* support of reentrant (pure) programming.
*
*
*____________________________________________________________________________
*
* When writing a program using these macros, the following rules apply:
*
* - Must include the file called CoreMacros.i . This file contains
* the following macros:
*
* DefineSections CallLib
* OpenLib CloseLib
* DefDS DS_BSS
* OnReEntrant OffReEntrant
*
* - Other macros must be included individually if they are used.
*
* - Must do the DefineSections macro at the start of the program.
* The other macros depend on this.
*
* - These macros must only be invoked from the CODE section.
*
*
*____________________________________________________________________________
*
*
* With the release of AmigaDOS 1.3, commands can be made resident using
* the RESIDENT command. Resident programs must be both reentrant and
* re-executable. A program which meets both these requirements is con-
* sidered pure.
*
* These macros support the creation of reentrant programming by using
* the A5 register to point to a block of memory in which uninitialized
* data is stored. This block of memory is used in place of the BSS
* section.
*
* Reentrant programs must begin by invoking the AllocUDS macro. They
* must end by invoking the FreeUDS macro. Refer to the file called
* PureTemplate for an example of how this is done.
*
*
*
*
*****************************************************************************
*****************************************************************************
*
* DefineSections MACRO 25 Dec 88
*
* NAME:
* DefineSections - Defines the DATA, BSS and CODE program sections.
*
* SYNOPSIS:
* DefineSections [<ProgramName>]
*
* FUNCTION:
* This macro defines the DATA, BSS and CODE program sections. This
* is required for the other macros to work correctly.
*
* If <ProgramName> is specified, the program unit will be given
* this name.
*
DefineSections MACRO
*-------------------------------; Start of DefineSections macro.
NOLIST
IFEQ NARG-1
LIST
IDNT "\1"
NOLIST
ENDC
IFND ReEntrant
ReEntrant SET 0
ENDC
IFND CAPE
LIST
MetacomcoFix: SECTION "",CODE ; This un-named code section
JMP CodeStart ; is needed to fix a bug in
; the MetaComCo assembler.
NOLIST
ENDC
LIST
DefDSPointer SET 0
CurrentLibID SET 0
SECTION CodeSection,CODE ; Relocatable code section
CodeStart:
SECTION DataSection,DATA ; Initialized data section
DataStart:
SECTION BSS_Section,BSS ; Un-initialized data section
BSS_Start:
SECTION CodeSection,CODE ; Relocatable code section
*-------------------------------; End of DefineSections macro.
ENDM
*****************************************************************************
*
* DefDS MACRO 26 Dec 88
*
* NAME:
* DefDS - Define an offset to a location in the RAM block used for
* un-initialized data storage.
*
* SYNOPSIS:
* DefDS <label>,<size>
*
* FUNCTION:
* This macro defines an offset to a location in the RAM block used
* for un-initialized data storage. The <label> is equated to this
* offset value. The data storage size will be <size> long words.
* This macro is used when the reentrant macro expansion feature is
* turned on.
*
* See also AllocUDS.
*
DefDS MACRO
NOLIST
IFND \1
\1 EQU DefDSPointer
DefDSPointer SET DefDSPointer+(4*\2)
ENDC
LIST
ENDM
*****************************************************************************
*****************************************************************************
*
* DS_BSS MACRO 13 Sept 88
*
* NAME:
* DS_BSS - Define data storage in a BSS section.
*
* SYNOPSIS:
* DS_BSS <label>,<size>,.B|.W|.L
*
* FUNCTION:
* This macro defines data storage in a BSS section. The <label> is
* equated to this value. The third argument tells whether the units
* of <size> are byte, word, or long.
*
DS_BSS MACRO
NOLIST
IFND \1
SECTION BSS_Section,BSS
IFC "\3",".W"
CNOP 0,2
ENDC
IFC "\3",".L"
CNOP 0,4
ENDC
\1:
DS\3 \2
SECTION CodeSection,CODE
ENDC
LIST
ENDM
*****************************************************************************
*
* OnReEntrant, OffReEntrant MACRO 13 Sept 88
*
* FUNCTION:
* These macros turn the reentrant macro expansion feature on or off.
*
* When the reentrant macro expansion feature is turned on, all
* BSS-type data space is in a block of RAM pointed to by A5.
*
* See also AllocUDS.
*
OnReEntrant MACRO
NOLIST
ReEntrant SET 1
LIST
ENDM
OffReEntrant MACRO
NOLIST
ReEntrant SET 0
LIST
ENDM
*****************************************************************************
*****************************************************************************
*
* CallLib MACRO 9 Feb 89
*
* NAME:
* CallLib - Call a subroutine of a library.
*
* SYNOPSIS:
* CallLib <SubroutineName>,<libname>
*
* FUNCTION:
* This macro calls a subroutine of a library. The library must
* have been previously opened, and the library pointer must be
* at <libname>.library.ptr .
*
* See also OpenLib.
*
CallLib MACRO
NOLIST
IFND _LVO\1.Ref
_LVO\1.Ref SET 1
LIST
XREF _LVO\1
NOLIST
ENDC
IFEQ ReEntrant-1
LIST
MOVE.L \2.library.ptr(A5),A6
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \2.library.ptr,A6
NOLIST
ENDC
LIST
JSR _LVO\1(A6)
ENDM
*****************************************************************************
*****************************************************************************
*
* OpenLib MACRO 25 Dec 88
*
* NAME:
* OpenLib - Open a library.
*
* SYNOPSIS:
* OpenLib <libname>
*
* Returns: pointer to the library at <libname>.ptr
*
* Z-flag = 1 if fail
*
* FUNCTION:
* This macro returns a pointer to a library that was previously
* installed into the system. If it is not successful, it will return
* a library pointer of zero and set the zero flag.
*
* See also CloseLib.
*
* INPUTS:
* <libname> - Typed in as the first argument of the macro.
*
* RESULTS:
* pointer to library - Returned in memory at the address labeled
* "<libname>.ptr".
*
* fail - Zero flag = true if failed, false if o.k.
*
OpenLib MACRO
*------------------------------; Start of OpenLib macro.
NOLIST
; Define _AbsExecBase and _LVOOpenLibrary if
IFND _AbsExecBase ; they have not yet been defined.
LIST
XREF _AbsExecBase
NOLIST
ENDC
IFND _LVOOpenLibrary
LIST
XREF _LVOOpenLibrary
NOLIST
ENDC
LIST
MOVE.L _AbsExecBase,A6 ; Do set-up for _LVOOpenLibrary.
CLR.L D0
MOVE.L #\1.str,A1
SECTION DataSection,DATA ; This is the <libname> ASCII string.
\1.str:
DC.B '\1',0
CNOP 0,2
SECTION CodeSection,CODE
JSR _LVOOpenLibrary(A6) ; Call OpenLibrary to open <libname>.
NOLIST
IFEQ ReEntrant-1
LIST
DefDS \1.ptr,1
MOVE.L D0,\1.ptr(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L D0,\1.ptr
DS_BSS \1.ptr,1,.L
NOLIST
ENDC
LIST
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of OpenLib macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* CloseLib exec.library MACRO Rev: 13 Sept 88
*
* NAME:
* CloseLib - Close a library.
*
* SYNOPSIS:
* CloseLib <libname>
*
* Returns: Nothing.
*
* FUNCTION:
* This macro tells the library manager that there is one fewer task
* currently using the specified library. This allows the operating
* system to purge the library from RAM if the extra RAM space is
* needed and no task is using it. Since this macro invokes the exec
* library (exec.library), the exec library should be closed last.
*
* See also OpenLib.
*
* INPUTS:
* <libname> - Typed in as the first argument of the macro.
* "<libname>.ptr" must have been created by the
* OpenLib macro.
*
* exec.library.ptr - Since this macro invokes the exec library, the
* exec library must have been opened previously
* by invoking the "OpenLib exec.library"
* macro command.
*
CloseLib MACRO
*------------------------------; Start of CloseLib macro.
; Put the library pointer in A1.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \1.ptr(A5),A1
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \1.ptr,A1
NOLIST
ENDC
LIST
CallLib CloseLibrary,exec ; Call CloseLibrary.
*------------------------------; End of CloseLib macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* AllocMem exec.library MACRO 13 Sept 88
*
* NAME:
* AllocMem - Allocate memory given certain requirements
*
* SYNOPSIS:
* AllocMem <MemBlockName>,D,<BlockSize> [,PUBLIC!CHIP!CLEAR]
* AllocMem <MemBlockName>,I,<PointerToBlockSize> [,PUBLIC!CHIP!CLEAR]
* AllocMem <MemBlockName>,R,D0 [,PUBLIC!CHIP!CLEAR]
*
* Returns: Start address of the memory block in D0 and
* at "<MemBlockName>.Adr"
* Block size saved at "<MemBlockName>.Size"
* Z-flag = 1 if fail.
*
* FUNCTION:
* This macro is used to get allocation of a block of memory. The
* first argument is the name you want the block to be called. This
* macro will create "<MemBlockName>.Adr", and "<MemBlockName>.Size"
* unless they already exist.
*
* For the third argument, either specify the number of bytes the
* block should contain (direct mode), point to the memory location
* where the block size is specified (indirect mode), or specify "D0"
* to have D0 specify the number of bytes (register mode).
*
* Specify PUBLIC if the memory is to be accessible by other tasks;
* otherwise, it will be private. Specify CHIP if the memory should
* be accessible by the custom chips; otherwise, it will try to use
* fast memory, if available. Specify CLEAR if you want the memory
* initialized to all zeros. If it is not successful, it will set
* the zero flag.
*
* See also FreeMem.
*
* INPUTS:
* "D","I" or "R" - Indicates "direct", "indirect" or "register"
* mode for the third argument.
*
* <MemBlockName> - The name you want the block to be called.
*
* <PointerToBlockSize> - Specifies number of bytes in the block.
* <BlockSize> or "D0"
*
* [PUBLIC!CHIP!CLEAR] - Type PUBLIC, CHIP, and/or CLEAR, separated
* by a "!".
*
* exec.library.LP - Must have been defined by invoking the
* "OpenLib exec.library" macro command.
*
AllocMem MACRO
*------------------------------; Start of AllocMem macro.
NOLIST
IFC "\2","D" ; If \3 uses direct mode, then.
LIST
; Put the block size in D0.
MOVE.L #\3,D0
NOLIST
ENDC
IFC "\2","I" ; If \3 uses indirect mode, then.
LIST
; Put the block size in D0.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \3(A5),D0
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \3,D0
NOLIST
ENDC
ENDC
LIST
; Save the block size at <MemBlockName>.Size
NOLIST
IFEQ ReEntrant-1
LIST
DefDS \1.Size,1
MOVE.L D0,\1.Size(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L D0,\1.Size
DS_BSS \1.Size,1,.L
NOLIST
ENDC
IFNE NARG-4 ; If \4 is not given, then
LIST
CLR.L D1 ; Accept any memory.
NOLIST
ENDC
IFEQ NARG-4 ; If \4 is given, then
PUBLIC SET 1
CHIP SET 2
CLEAR SET $10000
LIST
; Set the appropriate bits in D1.
MOVE.L #\4,D1
NOLIST
ENDC
LIST
CallLib AllocMem,exec ; Call AllocMem.
; Save the address of the memory block at
; <MemBlockName>.Adr
NOLIST
IFEQ ReEntrant-1
LIST
DefDS \1.Adr,1
MOVE.L D0,\1.Adr(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L D0,\1.Adr
DS_BSS \1.Adr,1,.L
NOLIST
ENDC
LIST
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of AllocMem macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* AllocUDS exec.library MACRO 19 Dec 88
*
* NAME:
* AllocUDS - Allocate memory for uninitialized data storage
*
* SYNOPSIS:
* AllocUDS <BlockSize>
*
* Returns: Start address of the memory block in A5.
* Z-flag = 1 if fail.
* Turns on reentrant programming mode.
*
* FUNCTION:
* This macro is used to allocate memory for uninitialized data
* storage for reentrant programs. This macro should be invoked
* at the beginning of reentrant programs.
*
* The value of <BlockSize> can be determined by equating <BlockSize>
* to DefDSPointer at the end of the program.
*
* See also FreeUDS, DefDS.
*
*
* INPUTS:
* <BlockSize> - Specifies number of bytes in the block.
*
*
AllocUDS MACRO
*------------------------------; Start of AllocUDS macro.
; Put block size in D0.
MOVE.L #\1,D0
CLR.L D1 ; Accept any memory.
NOLIST
; Define _AbsExecBase and _LVOAllocMem if
IFND _AbsExecBase ; they have not yet been defined.
LIST
XREF _AbsExecBase
NOLIST
ENDC
IFND _LVOAllocMem
LIST
XREF _LVOAllocMem
NOLIST
ENDC
LIST
MOVE.L _AbsExecBase,A6
JSR _LVOAllocMem(A6) ; Allocate the UDS memory block.
MOVEA.L D0,A5 ; Make A5 point to the UDS memory.
OnReEntrant ; Turn on reentrant programming.
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of AllocUDS macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* AvailMem exec.library MACRO 27 Dec 88
*
* NAME:
* AvailMem - Get size of memory available given certain requirements
*
* SYNOPSIS:
* AvailMem [ PUBLIC!CHIP!FAST ]
*
* Returns: Size of available memory in D0.
*
* FUNCTION:
* This macro returns the size of available memory given certain
* requirements. Specify PUBLIC if the memory is to be accessible by
* other tasks; otherwise, it will be private. Specify CHIP if the
* memory should be accessible by the custom chips; otherwise, it
* will try to use fast memory, if available. Specify FAST if it must
* be non-chip memory.
*
* INPUTS:
* [PUBLIC!CHIP!FAST] - Type PUBLIC, CHIP, and/or FAST, separated
* by a "!".
*
* exec.library.LP - Must have been defined by invoking the
* "OpenLib exec.library" macro command.
*
* RESULTS:
* size of free memory - Returned in D0.
*
AvailMem MACRO
*------------------------------; Start of AvailMem macro.
NOLIST
IFEQ NARG ; If \1 is not given, then
LIST
CLR.L D1 ; Accept any available memory.
NOLIST
ENDC
IFEQ NARG-1 ; If \1 is given, then
PUBLIC SET 1
CHIP SET 2
FAST SET 4
LIST
MOVEQ #\1,D1 ; Set the appropriate bits in D1.
NOLIST
ENDC
LIST
CallLib AvailMem,exec ; Call AvailMem.
*------------------------------; End of AvailMem macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Close dos.library MACRO 13 Sept 88
*
* NAME:
* Close - Close a directory or file.
*
* SYNOPSIS:
* Close <FileHandleName>
*
* Returns: Nothing.
*
* FUNCTION:
* This macro closes a directory or file.
*
* See also Open.
*
* INPUTS:
* <FileHandleName> - The name of the file to be removed.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
Close MACRO
*------------------------------; Start of Close macro.
; Put the file handle in D1.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \1(A5),D1
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \1,D1
NOLIST
ENDC
LIST
CallLib Close,dos ; Call Close to remove the file.
*------------------------------; End of Close macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* CreateDir dos.library MACRO 19 Dec 88
*
* NAME:
* CreateDir - Create a new directory.
*
* SYNOPSIS:
* CreateDir <DirLockName>,D,<DirName>
* CreateDir <DirLockName>,I,<PointerToDirName>
* CreateDir <DirLockName>,R,D1
*
* Returns: Shared read lock in D0 and at <DirLockName>.
* Z-flag = 1 if fail.
*
* FUNCTION:
* This macro creates a new directory with the name specified as
* <DirName>. The directory name is either specified directly as
* <DirName>, or indirectly as a string pointed to by D1 or by
* <PointerToDirName>. It returns a shared read lock in D0 and at
* <DirLockName>. If it is not successful, it will return a shared
* read lock of zero and set the zero flag.
*
* INPUTS:
* "D","I" or "R" - Indicates "direct", "indirect", or "register"
* mode for the third argument.
*
* <PointerToDirName>, - Pointer to a null-terminated directory name
* D1, or <DirName> string or the directory name itself.
*
* <DirLockName> - The name you want the read lock to be called.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* read lock - Returned in D0 and in memory at the address
* labeled "<DirLockName>".
*
* fail - Zero flag = true if failed, false if o.k.
*
CreateDir MACRO
*------------------------------; Start of CreateDir macro.
NOLIST
IFC '\2','I' ; If <PointerToDirName> is specified, then
LIST
; Put <PointerToDirName> in D1.
MOVE.L #\3,D1
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D1
NOLIST
ENDC
ENDC
IFC '\2','D' ; If <DirName> is specified, then
LIST
; Make D1 point to the directory name string.
MOVE.L #\3.str,D1
NOLIST
IFND \3.str ; Unless it was previously defined,
LIST
SECTION DataSection,DATA ; The ASCII directory name string goes here.
\3.str:
DC.B '\3',0
CNOP 0,2
SECTION CodeSection,CODE
NOLIST
ENDC
ENDC
LIST
CallLib CreateDir,dos ; Call CreateDir to create the directory.
; Put the dir read lock at <DirLockName>.
NOLIST
IFEQ ReEntrant-1
LIST
DefDS \1,1
MOVE.L D0,\1(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L D0,\1
DS_BSS \1,1,.L
NOLIST
ENDC
LIST
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of CreateDir macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* CurrentDir dos.library MACRO 14 Sept 88
*
* NAME:
* CurrentDir - Make the directory associated with a lock the current
* directory.
*
* SYNOPSIS:
* CurrentDir <NewDirLockName> [,<OldDirLockName>]
*
* Returns: Old dir lock in D0 and at "OldDirLock" or at
* <OldDirLockName> if it is specified.
* Z-flag = 1 if the old dir is the root of the
* initial startup disk.
*
* FUNCTION:
* This macro makes the directory associated with the <NewDirLockName>
* be the current directory. It returns a lock to the old directory
* in D0 and at the location "OldDirLock" or at "<OldDirLockName>" if
* "<OldDirLockName>" is specified. If the old directory was the root
* of the initial startup disk, the old-directory-lock will be zero
* and the zero flag will be set.
*
* See also Lock, ParentDir.
*
* INPUTS:
* <NewDirLockName> - This is the name of the directory lock which was
* returned by the Lock macro.
*
* <OldDirLockName> - The optional name you can specify for the old
* directory lock.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* old dir lock - Returned in D0 and in memory at the address
* labeled "OldDirLock" or "<OldDirLockName>".
*
* old was root - Zero flag = true if the old directory was the root.
*
CurrentDir MACRO
*------------------------------; Start of CurrentDir macro.
; Set up D1 for the _LVOCurrentDir function.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \1(A5),D1
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \1,D1
NOLIST
ENDC
LIST
CallLib CurrentDir,dos ; Call CurrentDir.
NOLIST
IFEQ NARG-2 ; If <OldDirLockName> is specified,
LIST
; Save the old dir lock under the specified
; name.
NOLIST
IFEQ ReEntrant-1
LIST
DefDS \2,1
MOVE.L D0,\2(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L D0,\2
DS_BSS \2,1,.L
NOLIST
ENDC
ENDC
IFEQ NARG-1
; If <OldDirLockName> is not specified, then
IFEQ ReEntrant-1
LIST
DefDS OldDirLock,1
MOVE.L D0,OldDirLock(A5) ; Save the old directory lock at "OldDirLock".
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L D0,OldDirLock ; Save the old directory lock at "OldDirLock".
DS_BSS OldDirLock,1,.L
NOLIST
ENDC
ENDC
LIST
TST.L D0 ; Make the zero flag indicate if old was root.
*------------------------------; End of CurrentDir macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* DateStamp dos.library MACRO 14 Sept 88
*
* NAME:
* DateStamp - Obtain the date and time in internal format
*
* SYNOPSIS:
* DateStamp
*
* Returns: # of days since Jan. 1, 1978 at "Time.ds_Days"
* # of minutes in day at "Time.ds_Minute"
* # if ticks in minute at "Time.ds_Tick"
*
* FUNCTION:
* This macro returns the date and time in the form of three longwords
* at "Time.ds_Days", "Time.ds_Minute", and "Time.ds_Tick".
* Note that the number of ticks is rounded off to the nearest 50
* ticks (one second).
*
* INPUTS:
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
DateStamp MACRO
*------------------------------; Start of DateStamp macro.
NOLIST
IFEQ ReEntrant-1
LIST
DefDS Time.ds_Days,1
DefDS Time.ds_Minute,1
DefDS Time.ds_Tick,1
NOLIST
ENDC
IFNE ReEntrant-1
LIST
DS_BSS Time.ds_Days,1,.L
DS_BSS Time.ds_Minute,1,.L
DS_BSS Time.ds_Tick,1,.L
NOLIST
ENDC
LIST
MOVE.L #Time.ds_Days,D1 ; Make D1 point to the date stamp buffer.
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D1
NOLIST
ENDC
LIST
CallLib DateStamp,dos ; Call DateStamp.
*------------------------------; End of DateStamp macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Delay dos.library MACRO 10 Jan 88
*
* NAME:
* Delay - Delay a process for a specified time.
*
* SYNOPSIS:
* Delay <timeout>
*
* Returns: Nothing.
*
* FUNCTION:
* This macro delays a process for a time specified by <timeout>.
* The delay time in units of one fiftieth of a second.
*
* See also WaitForChar.
*
* INPUTS:
* <timeout> - The delay time in units of one fiftieth of a
* second.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
Delay MACRO
*------------------------------; Start of Delay macro.
; Specify the timeout in D1.
MOVE.L #\1,D1
CallLib Delay,dos ; Call Delay.
*------------------------------; End of Delay macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* DeleteFile dos.library MACRO 19 Dec 88
*
* NAME:
* DeleteFile - Delete a directory or file.
*
* SYNOPSIS:
* DeleteFile D,<FileName>
* DeleteFile I,<PointerToFileName>
* DeleteFile R,D1
*
* Returns: Z-flag = 1 if fail.
*
* FUNCTION:
* This macro deletes a directory or file. The file name is either
* specified directly as <FileName>, or indirectly as a string
* pointed to by D1 or by <PointerToFileName>.
*
* INPUTS:
* "D","I" or "R" - Indicates "direct", "indirect", or "register"
* mode for the second argument.
*
* <PointerToFileName> - Pointer to a null-terminated file name string
* or <FileName> or the FileName itself.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
DeleteFile MACRO
*------------------------------; Start of DeleteFile macro.
NOLIST
IFC '\1','I' ; If <PointerToFileName> is specified, then
LIST
; Put <PointerToFileName> in D1.
MOVE.L #\2,D1
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D1
NOLIST
ENDC
ENDC
IFC '\1','D' ; If <FileName> is specified, then
LIST
; Make D1 point to <FileName>.
MOVE.L #\2.str,D1
NOLIST
IFND \2.str ; Unless it was previously defined,
LIST
SECTION DataSection,DATA ; The ASCII <FileName> string goes here.
\2.str:
DC.B '\2',0
CNOP 0,2
SECTION CodeSection,CODE
NOLIST
ENDC
ENDC
LIST
CallLib DeleteFile,dos ; Call DeleteFile to delete the file.
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of DeleteFile macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Disable MACRO 9 Feb 89
*
* NAME:
* Disable - Disable all interrupts.
*
* SYNOPSIS:
* Disable
*
* FUNCTION:
* This macro disables all interrupts. It may be unsafe to leave
* interrupts disabled for more than 250 microseconds.
*
* See also Enable.
*
Disable MACRO
*------------------------------; Start of Disable macro.
NOLIST
IFND _intena
LIST
XREF _intena
NOLIST
ENDC
IFEQ ReEntrant-1
LIST
MOVE.L exec.library.ptr(A5),A6
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L exec.library.ptr,A6
NOLIST
ENDC
LIST
MOVE.W #$4000,_intena
ADDQ.B #1,$126(A6) ; Increment IDNestCnt.
*------------------------------; End of Disable macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* DoCLICmd dos.library MACRO 14 Jan 88
*
* NAME:
* DoCLICmd - Do a CLI command.
*
* SYNOPSIS:
* DoCLICmd <CmdBufferPtr> [,<OutputFileHandleName>]
*
* Returns: Z-flag = 1 if fail.
*
* FUNCTION:
* This macro executes the command string pointed to by <CmdBufferPtr>
* as a CLI command. If the optional <OutputFileHandleName> is
* specified, the CLI command will send its data to the specified
* file. Otherwise, output will go to the current window. If it is
* not successful, it will set the zero flag.
*
* See also Execute.
*
* INPUTS:
* <CmdBufferPtr> - The pointer to the CLI command string to be
* executed.
*
* <OutputFileHandleName> - The optional output file specification. Use
* the file handle name which was defined for
* the "Open" macro.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* fail - Zero flag = true if failed, false if o.k.
*
DoCLICmd MACRO
*------------------------------; Start of DoCLICmd macro.
CLR.L D2 ; Make D2 indicate "execute from command
; string only".
NOLIST
IFEQ NARG-2 ; If the output file handle is specified, then
LIST
; Make D3 indicate the output file handle.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \2(A5),D3
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \2,D3
NOLIST
ENDC
ENDC
IFEQ NARG-1 ; If no output file handle is specified, then
LIST
CLR.L D3 ; Clear D3 so that output will go to the
; current window.
NOLIST
ENDC
LIST
; Make D1 point to the command buffer.
MOVE.L #\1,D1
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D1
NOLIST
ENDC
LIST
CallLib Execute,dos ; Call Execute to do the CLI command.
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of DoCLICmd macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Enable MACRO 9 Feb 89
*
* NAME:
* Enable - Enable interrupts.
*
* SYNOPSIS:
* Enable
*
* FUNCTION:
* This macro enables interrupts.
*
* See also Disable.
*
Enable MACRO
*------------------------------; Start of Enable macro.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L exec.library.ptr(A5),A6
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L exec.library.ptr,A6
NOLIST
ENDC
LIST
SUBQ.B #1,$126(A6) ; Decrement IDNestCnt.
BGE.S 5$
MOVE.W #$C000,_intena
5$:
*------------------------------; End of Enable macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Execute dos.library MACRO 14 Sept 88
*
* NAME:
* Execute - Execute CLI commands from a command file.
*
* SYNOPSIS:
* Execute <CmdFileHandleName> [,<OutputFileHandleName>]
*
* Returns: Z-flag = 1 if fail.
*
* FUNCTION:
* This macro executes CLI commands from the command file specified
* by <CmdFileHandleName>. If the optional <OutputFileHandleName> is
* specified, the CLI command will send its data to the specified
* file. Otherwise, output will go to the current window. If it is
* not successful, it will set the zero flag.
*
* See also DoCLICmd.
*
* INPUTS:
* <CmdFileHandleName> - The file handle name of the command file.
* Use the file handle name which was defined
* for the "Open" macro.
*
* <OutputFileHandleName> - The optional output file specification. Use
* the file handle name which was defined for
* the "Open" macro.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* fail - Zero flag = true if failed, false if o.k.
*
Execute MACRO
*------------------------------; Start of Execute macro.
MOVE.L #NullString,D1 ; Make D1 point to a null command string.
NOLIST
IFND NullString
LIST
SECTION DataSection,DATA
NullString:
DC.B 0,0
SECTION CodeSection,CODE
NOLIST
ENDC
IFEQ NARG-2 ; If the output file handle is specified, then
LIST
; Make D3 indicate the output file handle.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \2(A5),D3
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \2,D3
NOLIST
ENDC
ENDC
IFEQ NARG-1 ; If no output file handle is specified, then
LIST
CLR.L D3 ; Clear D3 so that output will go to the
; current window.
NOLIST
ENDC
LIST
; Put the command file handle in D2.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \1(A5),D2
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \1,D2
NOLIST
ENDC
LIST
CallLib Execute,dos ; Call Execute.
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of Execute macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Exist dos.library MACRO Rev: 19 Dec 88
*
* NAME:
* Exist - Find out if a directory or file exists.
*
* SYNOPSIS:
* Exist D,<FileName>
* Exist I,<PointerToFileName>
* Exist R,D1
*
* Returns: Z-flag = 0 if it exists.
* Z-flag = 1 if non-existent.
*
* FUNCTION:
* This macro checks to see if a specified file or directory exists.
* The file name is either specified directly as <FileName>, or
* indirectly as a string pointed to by D1 or by <PointerToFileName>.
*
* See also Lock.
*
* INPUTS:
* "D","I" or "R" - Indicates "direct", "indirect", or "register"
* mode for the second argument.
*
* <PointerToFileName> - Pointer to a null-terminated file name string
* or <FileName> or the FileName itself.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* existence - Z-flag = 0 if it exists or = 1 if non-existent.
*
Exist MACRO
*------------------------------; Start of Exist macro.
MOVEQ #-2,D2 ; Make D2 indicate the read accessMode.
NOLIST
IFC '\1','I' ; If <PointerToFileName> is specified, then
LIST
; Put <PointerToFileName> in D1.
MOVE.L #\2,D1
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D1
NOLIST
ENDC
ENDC
IFC '\1','D' ; If <FileName> is specified, then
LIST
; Make D1 point to <FileName>.str .
MOVE.L #\2.str,D1
NOLIST
IFND \2.str ; Unless it was previously defined,
LIST
SECTION DataSection,DATA ; The ASCII <FileName> string goes here.
\2.str:
DC.B '\2',0
CNOP 0,2
SECTION CodeSection,CODE
NOLIST
ENDC
ENDC
LIST
CallLib Lock,dos ; Call Lock to get a lock on <FileName>.
MOVE.L D0,-(A7) ; Save the lock which indicates existence.
MOVE.L D0,D1 ; Unlock the file.
CallLib UnLock,dos
MOVE.L (A7)+,D0 ; Get the lock back.
TST.L D0 ; Make the zero flag indicate existence.
*------------------------------; End of Exist macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* FindTask exec.library MACRO 19 Dec 88
*
* NAME:
* FindTask - Find a task with a given name or find oneself.
*
* SYNOPSIS:
* FindTask Self,<TaskStructPtrName>
* FindTask D,<TaskName>,<TaskStructPtrName>
* FindTask I,<PointerToTaskName>,<TaskStructPtrName>
* FindTask R,A1,<TaskStructPtrName>
*
* Returns: Pointer to the task structure in D0 and at
* <TaskStructPtrName>.
*
* FUNCTION:
* This macro returns a pointer to the specified task control
* structure. The file name is either specified as "Self", specified
* directly as <TaskName>, or indirectly as a string pointed to by
* either <PointerToTaskName> or A1.
*
* The pointer is returned in D0 and at <TaskStructPtrName>. This
* macro will create "<TaskStructPtrName>" if it does not already
* exists.
*
* INPUTS:
* "Self" - Specifies the current task.
*
* "D","I" or "R" - Indicates "direct", "indirect", or "register"
* mode for the second argument.
*
* <PointerToTaskName> - Pointer to a null-terminated task name string
* or <TaskName> or the task name itself.
*
* <TaskStructPtrName> - The name you want the pointer to the task
* structure to be called.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* task struct pointer - Returned in D0 and in memory at the address
* labeled "<TaskStructPtrName>".
*
FindTask MACRO
*------------------------------; Start of FindTask macro.
NOLIST
IFC '\1','I' ; If <PointerToTaskName> is specified, then
LIST
; Put <PointerToTaskName> in A1.
MOVEA.L #\2,A1
NOLIST
IFEQ ReEntrant-1
LIST
ADDA.L A5,A1
NOLIST
ENDC
ENDC
IFC '\1','D' ; If <TaskName> is specified, then
LIST
; Make A1 point to the task name string.
MOVEA.L #\2.str,A1
NOLIST
IFND \2.str ; Unless it was previously defined,
LIST
SECTION DataSection,DATA ; The ASCII <TaskName> string goes here.
\2.str:
DC.B '\2',0
CNOP 0,2
SECTION CodeSection,CODE
NOLIST
ENDC
ENDC
IFC '\1','Self' ; If "Self" is specified, then
LIST
SUBA.L A1,A1 ; Clear A1 to indicate "Self".
NOLIST
ENDC
LIST
CallLib FindTask,exec ; Call FindTask.
; Put the pointer to the task structure at
; <TaskStructPtrName>.
NOLIST
IFC '\1','Self'
IFEQ ReEntrant-1
LIST
DefDS \2,1
MOVE.L D0,\2(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
DS_BSS \2,1,.L
MOVE.L D0,\2
NOLIST
ENDC
ENDC
IFNC '\1','Self'
IFEQ ReEntrant-1
LIST
DefDS \3,1
MOVE.L D0,\3(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
DS_BSS \3,1,.L
MOVE.L D0,\3
NOLIST
ENDC
ENDC
LIST
*------------------------------; End of FindTask macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* FreeMem exec.library MACRO 14 Sept 88
*
* NAME:
* FreeMem - De-allocate memory
*
* SYNOPSIS:
* FreeMem <MemBlockName>
*
* Returns: Nothing.
*
* FUNCTION:
* This macro frees a block of memory which was previously allocated
* using the AllocMem macro.
*
* INPUTS:
* <MemBlockName>.Adr - Location where the pointer to the memory
* block is stored. This was created by the
* AllocMem macro.
*
* <MemBlockName>.Size - Location where the size of the memory
* block is stored. This was created by the
* AllocMem macro.
*
* exec.library.LP - Must have been defined by invoking the
* "OpenLib exec.library" macro command.
*
FreeMem MACRO
*------------------------------; Start of FreeMem macro.
; Make A1 point to the memory block start
; and put the block size in D0.
NOLIST
IFEQ ReEntrant-1
LIST
MOVEA.L \1.Adr(A5),A1
MOVE.L \1.Size(A5),D0
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVEA.L \1.Adr,A1
MOVE.L \1.Size,D0
NOLIST
ENDC
LIST
CallLib FreeMem,exec ; Call FreeMem.
*------------------------------; End of FreeMem macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* FreeUDS exec.library MACRO 25 Dec 88
*
* NAME:
* FreeUDS - Free memory which was allocated by AllocUDS
*
* SYNOPSIS:
* FreeUDS <BlockSize>
*
* Returns: Nothing.
*
* FUNCTION:
* This macro is used to free memory used for uninitialized data
* storage for reentrant programs. This macro should be invoked
* at the end of reentrant programs.
*
* The value of <BlockSize> should be the same as that used by
* the AllocUDS macro.
*
*
* INPUTS:
* <BlockSize> - Specifies number of bytes in the block.
*
*
FreeUDS MACRO
*------------------------------; Start of FreeUDS macro.
MOVEA.L A5,A1
MOVE.L #\1,D0
NOLIST ; Define _LVOAllocMem if not already defined.
IFND _LVOFreeMem
LIST
XREF _LVOFreeMem
NOLIST
ENDC
LIST
MOVE.L _AbsExecBase,A6
JSR _LVOFreeMem(A6) ; Allocate the UDS memory block.
*------------------------------; End of FreeUDS macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* GetPrefs intuition.library MACRO 14 Sept 88
*
* NAME:
* GetPrefs - Get the preference settings.
*
* SYNOPSIS:
* GetPrefs I,<MemBlockName>
*
* GetPrefs D,<BufferStartAddr>
* GetPrefs D,<BufferStartAddr>,<BufferSize>
*
* Returns: Preference settings in the buffer.
*
* FUNCTION:
* This macro gets the preferences data and puts it into a buffer.
* The buffer is either specified indirectly by a vector located at
* <MemBlockName>.Adr or directly by <BufferStartAddr>.
*
* If no third argument is given, and <BufferStartAddr> is specified,
* the label "<BufferStartAddr>End" must exist one byte past the end
* of the buffer.
*
* If no third argument is given, and <MemBlockName> is specified,
* the buffer size must be specified in "<MemBlockName>.Size"
* The AllocMem macro takes care of this.
*
* INPUTS:
* "D" or "I" - Indicates "direct" or "indirect" mode for
* the second argument.
*
* <BufferStartAddr> - Defined for the start of the buffer.
*
* <MemBlockName>.Adr - Location where the pointer to the memory
* block is stored. This was created by the
* AllocMem macro.
*
* buffer start address - Specified as <BufferStartAddr>, or at
* <MemBlockName>.Adr
*
* buffer size - Specified as <BufferSize>, or at
* <MemBlockName>.Size, or as <BufferStartAddr>
* minus <BufferStartAddr>End.
*
* intuition.library.LP - Must have been defined by invoking the
* "OpenLib intuition.library" macro command.
*
* RESULTS:
* preferences data - Returned in the buffer.
*
GetPrefs MACRO
*------------------------------; Start of GetPrefs macro.
NOLIST
IFC '\1','D' ; If <BufferStartAddr> is specified, then
LIST
; Make A0 point to the start of the buffer.
MOVE.L #\2,A0
NOLIST
IFEQ NARG-2 ; If <BufferSize> is given, then
LIST
; Put <BufferSize> in D0.
MOVE.L #\3,D0
NOLIST
ENDC
IFEQ NARG-2 ; If there is no third argument, then
LIST
; Calculate buffer size as
; <BufferStartAddr>End minus
; <BufferStartAddr>. Put it in D0.
MOVE.L \2End-\2,D0
NOLIST
ENDC
ENDC
IFNC '\1','I' ; If <MemBlockName> is specified, then
LIST
; Get the buffer start address from
; <MemBlockName>.Adr , and get the buffer
; Size from <MemBlockName>.Size
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \2.Adr(A5),A0
MOVE.L \2.Size(A5),D0
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \2.Adr,A0
MOVE.L \2.Size,D0
NOLIST
ENDC
ENDC
LIST
; Call GetPrefs.
CallLib GetPrefs,intuition
*------------------------------; End of GetPrefs macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* GetStdIn dos.library MACRO 14 Sept 88
*
* NAME:
* GetStdIn - Get a file handle for the program's initial output.
*
* SYNOPSIS:
* GetStdIn
* Returns: File handle in D0 and at StdIn.
*
* FUNCTION:
* This macro returns a file handle for the program's initial input.
* This file handle will usually be associated with the CLI window,
* unless input was redirected from the command line.
*
* INPUTS:
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* file handle - Returned in D0 and in memory at the address
* labeled "StdIn".
*
*
GetStdIn MACRO
*------------------------------; Start of GetStdIn macro.
CallLib Input,dos ; Call Input.
NOLIST
IFEQ ReEntrant-1
LIST
DefDS StdIn,1
MOVE.L D0,StdIn(A5) ; Save the file handle at StdIn.
NOLIST
ENDC
IFNE ReEntrant-1
LIST
DS_BSS StdIn,1,.L
MOVE.L D0,StdIn ; Save the file handle at StdIn.
NOLIST
ENDC
LIST
*------------------------------; End of GetStdIn macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* GetStdOut dos.library MACRO 14 Sept 88
*
* NAME:
* GetStdOut - Get a file handle for the program's initial output.
*
* SYNOPSIS:
* GetStdOut
* Returns: File handle in D0 and at StdOut.
*
* FUNCTION:
* This macro returns a file handle for the program's initial output.
* This file handle will usually be associated with the CLI window,
* unless output was redirected from the command line.
*
* INPUTS:
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* file handle - Returned in D0 and in memory at the address
* labeled "StdOut".
*
*
GetStdOut MACRO
*------------------------------; Start of GetStdOut macro.
CallLib Output,dos ; Call Output.
NOLIST
IFEQ ReEntrant-1
LIST
DefDS StdOut,1
MOVE.L D0,StdOut(A5) ; Save the file handle at StdOut.
NOLIST
ENDC
IFNE ReEntrant-1
LIST
DS_BSS StdOut,1,.L
MOVE.L D0,StdOut ; Save the file handle at StdOut.
NOLIST
ENDC
LIST
*------------------------------; End of GetStdOut macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* IoErr dos.library MACRO 18 Sept 88
*
* NAME:
* IoErr - Obtain the error code for the I/O error condition.
*
* SYNOPSIS:
* IoErr
*
* Returns: I/O error code in D0 and at IoErrCode.
*
* FUNCTION:
* This macro returns the I/O error code in D0 and at IoErrCode.
*
* INPUTS:
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
IoErr MACRO
*------------------------------; Start of IoErr macro.
CallLib IoErr,dos ; Call IoErr.
NOLIST
IFEQ ReEntrant-1
LIST
DefDS IoErrCode,1 ; Save error code at IoErrCode
MOVE.L D0,IoErrCode(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
DS_BSS IoErrCode,1,.L ; Save error code at IoErrCode
MOVE.L D0,IoErrCode
NOLIST
ENDC
LIST
*------------------------------; End of IoErr macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Lock dos.library MACRO 19 Dec 88
*
* NAME:
* Lock - Obtain a lock on a directory or file.
*
* SYNOPSIS:
* Lock D,<FileName>,<LockName>,read | write
* Lock I,<PointerToFileName>,<LockName>,read | write
* Lock R,D1,<LockName>,read | write
*
* Returns: Lock in D0 and at <LockName>.
* Z-flag = 1 if fail.
*
* FUNCTION:
* This macro returns a lock for a file or directory. The file name
* is either specified directly as <FileName>, or indirectly as a
* string pointed to by D1 or by <PointerToFileName>. If it is not
* successful, it will return a file handle of zero and set the zero
* flag.
*
* See also UnLock.
*
* INPUTS:
* "D","I" or "R" - Indicates "direct", "indirect", or "register"
* mode for the second argument.
*
* <PointerToFileName> - Pointer to a null-terminated file name string
* or <FileName> or the FileName itself.
*
* <LockName> - The name you want the lock to be called.
*
* read | write - Must specify whether the file is a shared read
* lock or an exclusive write lock. Must be lower
* case.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* file lock - Returned in D0 and in memory at the address
* labeled "<LockName>".
*
* fail - Zero flag = true if failed, false if o.k.
*
Lock MACRO
*------------------------------; Start of Lock macro.
NOLIST
IFC '\4','read'
LIST
MOVEQ #-2,D2 ; Make D2 indicate the read accessMode.
NOLIST
ENDC
IFC '\4','write'
LIST
MOVEQ #-1,D2 ; Make D2 indicate the write accessMode.
NOLIST
ENDC
IFC '\1','I' ; If <PointerToFileName> is specified, then
LIST
; Put <PointerToFileName> in D1.
MOVE.L #\2,D1
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D1
NOLIST
ENDC
ENDC
IFC '\1','D' ; If <FileName> is specified, then
LIST
; Make D1 point to <FileName>.str .
MOVE.L #\2.str,D1
NOLIST
IFND \2.str ; Unless it was previously defined,
LIST
SECTION DataSection,DATA ; The ASCII <FileName> string goes here.
\2.str:
DC.B '\2',0
CNOP 0,2
SECTION CodeSection,CODE
NOLIST
ENDC
ENDC
LIST
CallLib Lock,dos ; Call Lock to get a lock on <FileName>.
; Put the lock at <LockName>.
NOLIST
IFEQ ReEntrant-1
LIST
DefDS \3,1
MOVE.L D0,\3(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
DS_BSS \3,1,.L
MOVE.L D0,\3
NOLIST
ENDC
LIST
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of Lock macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Open dos.library MACRO 19 Dec 88
*
* NAME:
* Open - Open a file.
*
* SYNOPSIS:
* Open D,<FileName>,<FileHandleName> [,new | read | r/w]
* [or with D0 = 0 if new]
*
* Open I,<PointerToFileName>,<FileHandleName> [,new | read | r/w]
* [or with D0 = 0 if new]
*
* Open R,D1,<FileHandleName> [,new | read | r/w]
* [or with D0 = 0 if new]
*
* Returns: File handle in D0 and at <FileHandleName>.
* Z-flag = 1 if fail.
*
* FUNCTION:
* This macro returns a file handle for a file. The file name is
* either specified directly as <FileName>, or indirectly as a string
* pointed to by D1 or by <PointerToFileName>.
*
* If it is not successful, it will return a file handle of zero and
* set the zero flag.
*
* See also Close.
*
* INPUTS:
* "D","I" or "R" - Indicates "direct", "indirect", or "register"
* mode for the second argument.
*
* <PointerToFileName> - Pointer to a null-terminated file name string
* or <FileName> or the FileName itself.
*
* <FileHandleName> - The name you want the file handle to be called.
*
* new | read | r/w - Specifys whether a new file should be created or
* an existing file should be used. For existing
* files, "read" indicates that a shared read lock
* is needed, "r/w" indicates that an exclusive
* lock is needed. Must be lower case.
*
* D0 = 0 if new - If new, read, or r/w is not specified, D0 tells
* the macro whether the file to be opened is a
* new file (D0 = 0) or existing r/w (D0 not 0).
* Use the Lock macro to establish D0.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* file handle - Returned in D0 and in memory at the address
* labeled "<FileHandleName>".
*
* fail - Zero flag = true if failed, false if o.k.
*
Open MACRO
*------------------------------; Start of Open macro.
NOLIST
IFEQ NARG-4 ; If new, read, or r/w is specified, make D2
; indicate the accessMode accordingly.
IFC '\4','new'
LIST
MOVE.L #1006,D2 ; Make D2 indicate "new" access mode.
NOLIST
ENDC
IFC '\4','read'
LIST
MOVE.L #1005,D2 ; Make D2 indicate "read" access mode.
NOLIST
ENDC
IFC '\4','r/w'
LIST
MOVE.L #1004,D2 ; Make D2 indicate "r/w" access mode.
NOLIST
ENDC
ENDC
IFEQ NARG-3 ; If new, read, or r/w is not specified,
LIST
MOVE.L #1005,D2 ; Make D2 indicate the old/new accessMode
TST D0 ; based on D0.
BNE 5$
SUBQ #1,D2
5$:
NOLIST
ENDC
IFC '\1','I' ; If <PointerToFileName> is specified, then
LIST
; Put <PointerToFileName> in D1.
MOVE.L #\2,D1
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D1
NOLIST
ENDC
ENDC
IFC '\1','D' ; If <FileName> is specified, then
LIST
; Make D1 point to the file name string.
MOVE.L #\2.str,D1
NOLIST
IFND \2.str ; Unless it was previously defined,
LIST
SECTION DataSection,DATA ; The ASCII <FileName> string goes here.
\2.str:
DC.B '\2',0
CNOP 0,2
SECTION CodeSection,CODE
NOLIST
ENDC
ENDC
LIST
CallLib Open,dos ; Call Open to open <FileName>.
; Put the file handle at <FileHandleName>.
NOLIST
IFEQ ReEntrant-1
LIST
DefDS \3,1
MOVE.L D0,\3(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
DS_BSS \3,1,.L
MOVE.L D0,\3
NOLIST
ENDC
LIST
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of Open macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* ParentDir dos.library MACRO 15 Sept 88
*
* NAME:
* ParentDir - Obtain the lock for the parent directory of the
* specified file or directory
*
* SYNOPSIS:
* ParentDir <ParentDirLockName> [,<FileLockName>]
* [ or FileLock in D0 ]
*
* Returns: Parent dir lock in D0 and at
* <ParentDirLockName>.
* Z-flag = 1 if the parent dir is the root of the
* current filing system.
*
* FUNCTION:
* This macro obtains the lock for the parent directory of the file
* specified by <FileLockName> or alternately specified by the file
* lock in D0. It returns a lock to the parent directory in D0 and at
* the location "<ParentDirLockName>". If the parent dir is the root
* of the current filing system, the parent directory lock will be
* zero and the zero flag will be set.
*
* See also CurrentDir, Lock.
*
* INPUTS:
* [<FileLockName>] - This is the name of the directory lock which was
* returned by the Lock macro. If this is not
* specified, D0 must contain the file lock.
*
* <ParentDirLockName> - The name you want the parent directory lock
* to be called.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* parent dir lock - Returned in D0 and in memory at the address
* labeled "<ParentDirLockName>".
*
* parent was root - Zero flag = true if the parent directory was the
* root.
*
ParentDir MACRO
*------------------------------; Start of ParentDir macro.
NOLIST
IFEQ NARG-2 ; If <FileLockName> is given, then
LIST
; Get the file lock from <FileLockName>.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \2(A5),D1
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \2,D1
NOLIST
ENDC
ENDC
IFEQ NARG-1 ; If <FileLockName> is not given, then
LIST
MOVE.L D0,D1 ; Use the file lock given in D0.
NOLIST
ENDC
LIST
CallLib ParentDir,dos ; Call ParentDir.
; Save the parent directory lock at the named
; location.
NOLIST
IFEQ ReEntrant-1
LIST
DefDS \1,1
MOVE.L D0,\1(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
DS_BSS \1,1,.L
MOVE.L D0,\1
NOLIST
ENDC
LIST
TST.L D0 ; Make the zero flag indicate if parent dir
; was the root.
*------------------------------; End of ParentDir macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Read dos.library MACRO 21 Dec 88
*
* NAME:
* Read - Read a file into a buffer.
*
* SYNOPSIS:
* Read <FileHandleName>,D,<BufferStartAddr>
* Read <FileHandleName>,D,<BufferStartAddr>,D3
* Read <FileHandleName>,D,<BufferStartAddr>,<BufferSize>
*
* Read <FileHandleName>,I,<MemBlockName>
* Read <FileHandleName>,I,<MemBlockName>,D3
* Read <FileHandleName>,I,<MemBlockName>,<BufferSize>
*
* Returns: Data which was read in the buffer.
* Actual length of bytes read in D0 and at
* <BufferStartAddr>.Len or <MemBlockName>.Len.
* Z-flag = 1 if fail.
*
* FUNCTION:
* This macro reads bytes from an opened file into a buffer. The
* buffer is either specified by <BufferStartAddr> or by a vector
* located at <MemBlockName>.Adr .
*
* If no fourth argument is given, and <BufferStartAddr> is
* specified, the label "<BufferStartAddr>End" must exist one byte
* past the end of the buffer.
*
* If no fourth argument is given, and <MemBlockName> is specified,
* the buffer size must be specified in <MemBlockName>.Size .
*
* D3 may be used to specify the buffer size, or the buffer size may
* be specified directly as <BufferSize>.
*
* If "<BufferStartAddr>" is given as the third argument, then
* "<BufferStartAddr>.Len" will be created, if it doesn't already
* exist, so that the actual length may be stored there.
*
* If "<MemBlockName>" is given as the third argument, then
* "<MemBlockName>.Len" will be created, if it doesn't already
* exist, so that the actual length may be stored there.
*
* If it is not successful, it will set the zero flag.
*
* See also Seek.
*
* INPUTS:
* "D" or "I" - Indicates "direct" or "indirect" mode for
* the third argument.
*
* <FileHandleName> - Typed in as the first argument of the macro.
* Use the Open macro to create this.
*
* <BufferStartAddr> - Defined for the start of the buffer.
*
* <MemBlockName> - This is the same <MemBlockName> argument which
* was used for the AllocMem macro.
*
* buffer size - Specified in D3, or as <BufferSize>, or at
* <MemBlockName>.Size, or as <BufferStart
* Addr>End minus <BufferStartAddr>.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* read data - Returned in the buffer labeled "<BufferName>".
*
* actual length - Returns actual length of bytes read in D0 and at
* <BufferStartAddr>.Len or <MemBlockName>.Len.
*
* fail - Zero flag = true if failed, false if o.k.
*
Read MACRO
*------------------------------; Start of Read macro.
; Put the file handle in D1.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \1(A5),D1
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \1,D1
NOLIST
ENDC
LIST
; Make D2 point to the start of the buffer.
NOLIST
IFC '\2','D'
LIST
MOVE.L #\3,D2
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D2
NOLIST
ENDC
ENDC
IFC '\2','I'
IFEQ ReEntrant-1
LIST
MOVE.L \3.Adr(A5),D2
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \3.Adr,D2
NOLIST
ENDC
ENDC
IFEQ NARG-3 ; If there is no fourth argument, and
IFC '\2','D' ; <BufferStartAddr> is specified, then
LIST
; Calculate the buffer size as
; <BufferStartAddr>End minus
; <BufferStartAddr>. Put it in D3.
MOVE.L #\3End-\3,D3
NOLIST
ENDC
IFC '\2','I' ; If <MemBlockName> is specified, then
LIST
; Get the buffer size from <MemBlockName>.Size
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \3.Size(A5),D3
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \3.Size,D3
NOLIST
ENDC
ENDC
ENDC
IFEQ NARG-4 ; If the fourth argument exists,
IFNC '\4','D3' ; and it is not "D3", then
LIST
; Use the buffer size of the fourth argument.
MOVE.L #\4,D3
NOLIST
ENDC
ENDC
LIST
CallLib Read,dos ; Call Read.
; Store the actual length read at \3.Len .
NOLIST
IFEQ ReEntrant-1
LIST
DefDS \3.Len,1
MOVE.L D0,\3.Len(A5)
NOLIST
ENDC
IFNE ReEntrant-1
LIST
DS_BSS \3.Len,1,.L
MOVE.L D0,\3.Len
NOLIST
ENDC
LIST
CMPI.L #-1,D0 ; Make the zero flag indicate failure.
*------------------------------; End of Read macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Rename dos.library MACRO 19 Dec 88
*
* NAME:
* Rename - Rename a directory or file
*
* SYNOPSIS:
* Rename D,<OldNameString>,D,<NewNameString>
* Rename D,<OldNameString>,I,<PointerToNewNameString>
* Rename D,<OldNameString>,R,D2
*
* Rename I,<PointerToOldNameString>,D,<NewNameString>
* Rename I,<PointerToOldNameString>,I,<PointerToNewNameString>
* Rename I,<PointerToOldNameString>,R,D2
*
* Rename R,D1,D,<NewNameString>
* Rename R,D1,I,<PointerToNewNameString>
* Rename R,D1,R,D2
*
* Returns: Z-flag = 1 if fail.
*
* FUNCTION:
* This macro renames a file or directory specified by the "old name
* string" with the name specified by "new name string". The "name
* strings" must be null-terminated. If it is not successful, it will
* set the zero flag.
*
* INPUTS:
* "D","I" or "R" - Indicates "direct", "indirect", or
* "register" mode for the second and fourth
* arguments.
*
* <PointerToOldNameString> - The pointer to the name the file should be
* changrd from.
*
* <PointerToNewNameString> - The pointer to the name the file should be
* changrd to.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* fail - Zero flag = true if failed, false if o.k.
*
Rename MACRO
*------------------------------; Start of Rename macro.
NOLIST
IFC '\1','I' ; If <PointerToOldNameString> is specified,
LIST
; Put <PointerToOldNameString> in D1.
MOVE.L #\2,D1
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D1
NOLIST
ENDC
ENDC
IFC '\1','D' ; If <OldNameString> is specified, then
LIST
; Make D1 point to <OldNameString>.
MOVE.L #\2.str,D1
NOLIST
IFND \2.str ; Unless it was previously defined,
LIST
SECTION DataSection,DATA ; The ASCII <OldNameString> string goes here.
\2.str:
DC.B '\2',0
CNOP 0,2
SECTION CodeSection,CODE
NOLIST
ENDC
ENDC
IFC '\3','I' ; If <PointerToNewNameString> is specified,
LIST
; Put <PointerToNewNameString> in D1.
MOVE.L #\4,D1
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D1
NOLIST
ENDC
ENDC
IFC '\3','D' ; If <NewNameString> is specified, then
LIST
; Make D1 point to <NewNameString>.
MOVE.L #\4.str,D1
NOLIST
IFND \4.str ; Unless it was previously defined,
LIST
SECTION DataSection,DATA ; The ASCII <NewNameString> string goes here.
\4.str:
DC.B '\4',0
CNOP 0,2
SECTION CodeSection,CODE
NOLIST
ENDC
ENDC
LIST
CallLib Rename,dos ; Call Rename.
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of Rename macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Seek dos.library MACRO 15 Sept 88
*
* NAME:
* Seek - Move the read/write cursor position in a file and get the
* old position
*
* SYNOPSIS:
* Seek <FileHandleName> [,<offset> [, FromCurrent | BeforeEnd ] ]
*
* Returns: Old cursor position D0.
* Z-flag = 1 if fail.
*
* FUNCTION:
* This macro moves the read/write cursor position in a file, and
* returns the old cursor position. If only the <FileHandleName> is
* specified, the macro reads the position without moving the
* position. If niether FromCurrent or BeforeEnd is specified, the
* position is relative to the beginning of the file. If it is not
* successful, it will set the zero flag.
*
* See also Read, Write.
*
* INPUTS:
* <FileHandleName> - Typed in as the first argument of the macro.
* Use the Open macro to create this.
*
* [<offset>] - Value of the offset from start, from current or
* before the end.
*
* [ FromCurrent ] - Specifies that offset is from current position
* [ or BeforeEnd ] or before the end. If offset is specified
* without specifing FromCurrent or BeforeEnd,
* offset will be from the beginning. This macro
* argument may not be given if offset is not also
* given.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* old position - Returned in D0.
*
* fail - Zero flag = true if failed, false if o.k.
*
Seek MACRO
*------------------------------; Start of Seek macro.
; Put the file handle in D1.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \1(A5),D1
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \1,D1
NOLIST
ENDC
IFEQ NARG-1 ; If only the file handle was given, then
LIST
CLR.L D2 ; Make offset be zero from current.
CLR.L D3
NOLIST
ENDC
IFEQ NARG-2 ; If offset was given without argument #3,
LIST
; Make offset be from the beginning.
MOVE.L #\2,D2
MOVEQ.L #-1,D3
NOLIST
ENDC
IFEQ NARG-3 ; If FromCurrent or BeforeEnd is specified,
IFC '\3','FromCurrent'
LIST
CLR.L D3 ; Make offset from current.
MOVE.L #\2,D2
NOLIST
ENDC
IFC '\3','BeforeEnd'
LIST
MOVEQ #1,D3 ; Make offset before end.
MOVE.L #-\2,D2
NOLIST
ENDC
ENDC
LIST
CallLib Seek,dos ; Call Seek.
CMPI.L #-1,D0 ; Make the zero flag indicate failure.
*------------------------------; End of Seek macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* SetComment dos.library MACRO 15 Sept 88
*
* NAME:
* SetComment - Set a comment on a file or directory
*
* SYNOPSIS:
* SetComment <PointerToFileNameString>,<PointerToCommentString>
*
* Returns: Z-flag = 1 if fail.
*
* FUNCTION:
* This macro sets a comment on a file or directory specified by the
* "file name string". The "comment string" must be no more than 80
* characters long. Both strings must be null-terminated. If it is
* not successful, it will set the zero flag.
*
* INPUTS:
* <PointerToFileNameString> - The pointer to the name of the file.
*
* <PointerToCommentString> - The pointer to the comment string.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* fail - Zero flag = true if failed, false if o.k.
*
SetComment MACRO
*------------------------------; Start of SetComment macro.
; Do set-up for _LVOSetComment.
MOVE.L #\1,D1
MOVE.L #\2,D2
NOLIST
IFEQ ReEntrant-1
LIST
ADD.L A5,D1
ADD.L A5,D2
NOLIST
ENDC
LIST
CallLib SetComment,dos ; Call SetComment.
TST.L D0 ; Make the zero flag indicate failure.
*------------------------------; End of SetComment macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* UnLock dos.library MACRO 15 Sept 88
*
* NAME:
* UnLock - Unlock a directory or file.
*
* SYNOPSIS:
* UnLock <LockName>
*
* Returns: Nothing.
*
* FUNCTION:
* This macro unlocks a directory or file.
*
* See also Lock.
*
* INPUTS:
* <LockName> - The name of the lock to be removed.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
UnLock MACRO
*------------------------------; Start of UnLock macro.
; Put the lock in D1.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \1(A5),D1
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \1,D1
NOLIST
ENDC
LIST
CallLib UnLock,dos ; Call UnLock to remove the lock.
*------------------------------; End of UnLock macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* WaitForChar dos.library MACRO 15 Sept 88
*
* NAME:
* WaitForChar - Wait for a character to arrive at a virtual terminal
* within a time limit
*
* SYNOPSIS:
* WaitForChar <FileHandleName>,<timeout>
*
* Returns: Z-flag = 0 if char is available
* Z-flag = 1 if char is not available
*
* FUNCTION:
* This macro waits for a character to arrive at a virtual terminal
* (i.e. window), or for a specified amount of time to elapse,
* whichever occurs first. The value of <timeout> is specified in
* hundredths of seconds.
*
* INPUTS:
* <FileHandleName> - Typed in as the first argument of the macro.
* Use the Open macro to create this.
*
* <timeout> - The maximum time to wait in hundredths of
* seconds.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* Char available - Zero flag = true if char is not available.
* or not available = false if char is available.
*
WaitForChar MACRO
*------------------------------; Start of WaitForChar macro.
; Put file handle in D1.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \1(A5),D1
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \1,D1
NOLIST
ENDC
LIST
; Put timeout in D2.
MOVE.L #\2*10000,D2
CallLib WaitForChar,dos ; Call WaitForChar.
TST.L D0 ; Make the Z-flag indicate char availability.
*------------------------------; End of WaitForChar macro.
ENDM
*****************************************************************************
*****************************************************************************
*
* Write dos.library MACRO 21 Dec 88
*
* NAME:
* Write - Write to a file from a buffer.
*
* SYNOPSIS:
* Write D,<BufferStartAddr>,<FileHandleName>
* Write D,<BufferStartAddr>,<FileHandleName>,D3
* Write D,<BufferStartAddr>,<FileHandleName>,<BufferSize>
*
* Write R,D2,<FileHandleName>,D3
* Write R,D2,<FileHandleName>,<BufferSize>
*
* Write I,<MemBlockName>,<FileHandleName>
* Write I,<MemBlockName>,<FileHandleName>,D3
* Write I,<MemBlockName>,<FileHandleName>,<BufferSize>
*
* Returns: Actual length of bytes written in D0.
* Z-flag = 1 if fail.
*
* FUNCTION:
* This macro writes bytes from a buffer to an opened file. The buffer
* is either specified by a vector located at <MemBlockName>.Adr or
* by <BufferStartAddr>.
*
* If no fourth argument is given, and <BufferStartAddr> is
* specified, the label "<BufferStartAddr>End" must exist one byte
* past the end of the buffer.
*
* If no fourth argument is given, and <MemBlockName> is specified,
* the buffer size must be specified in <MemBlockName>.Size .
*
* D3 may be used to specify the buffer size, or the buffer size may
* be specified directly as <BufferSize>.
*
* If it is not successful, it will set the zero flag.
*
* INPUTS:
* "D","I" or "R" - Indicates "direct", "indirect", or "register"
* mode for the second argument.
*
* <FileHandleName> - Typed in as the third argument of the macro.
* Use the Open macro to create this.
*
* <BufferStartAddr> - Defined for the start of the buffer.
*
* <MemBlockName> - This is the same <MemBlockName> argument which
* was used for the AllocMem macro.
*
* buffer size - Specified in D3, or as <BufferSize>, or at
* <MemBlockName>.Size, or as
* <BufferStartAddr>End minus <BufferStartAddr>.
*
* dos.library.LP - Must have been defined by invoking the
* "OpenLib dos.library" macro command.
*
* RESULTS:
* actual length - Returns actual length of bytes written in D0.
*
* fail - Zero flag = true if failed, false if o.k.
*
Write MACRO
*------------------------------; Start of Write macro.
; Put the file handle in D1.
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \3(A5),D1
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \3,D1
NOLIST
ENDC
LIST
; Make D2 point to the start of the buffer.
NOLIST
IFC '\1','D'
LIST
MOVE.L #\2,D2
NOLIST
ENDC
IFC '\1','I'
IFEQ ReEntrant-1
LIST
MOVE.L \2.Adr(A5),D2
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \2.Adr,D2
NOLIST
ENDC
ENDC
IFEQ NARG-3 ; If there is no fourth argument, and
IFC '\1','D' ; <BufferStartAddr> is specified, then
LIST
; Calculate the buffer size as
; <BufferStartAddr>End minus
; <BufferStartAddr>. Put it in D3.
MOVE.L #\2End-\2,D3
NOLIST
ENDC
IFC '\1','I' ; If <MemBlockName> is specified, then
LIST
; Get the buffer size from <MemBlockName>.Size
NOLIST
IFEQ ReEntrant-1
LIST
MOVE.L \2.Size(A5),D3
NOLIST
ENDC
IFNE ReEntrant-1
LIST
MOVE.L \2.Size,D3
NOLIST
ENDC
ENDC
ENDC
IFEQ NARG-4 ; If the fourth argument exists,
IFNC '\4','D3' ; and it is not "D3", then
LIST
; Use the buffer size of the fourth argument.
MOVE.L #\4,D3
NOLIST
ENDC
ENDC
LIST
CallLib Write,dos ; Call Write.
CMPI.L #-1,D0 ; Make the zero flag indicate failure.
*------------------------------; End of Write macro.
ENDM
*****************************************************************************